package com.yunti.springboot.job;


import com.yunti.springboot.job.constant.ScheduleConstants;
import com.yunti.springboot.po.TaskJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.BeanUtils;

import java.util.Date;

/**
 * 抽象quartz调用
 *
 * @author icbc
 */
@Slf4j
public abstract class AbstractQuartzJob implements Job
{

    /**
     * 线程本地变量
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    @Override
    public void execute(JobExecutionContext context)
    {
        TaskJob taskJob = new TaskJob();
        BeanUtils.copyProperties(context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES),taskJob);
        try
        {
            before(context, taskJob);
            if (taskJob != null)
            {
                doExecute(context, taskJob);
            }
            after(context, taskJob, null);
        }
        catch (Exception e)
        {
            log.error("任务执行异常  - ：", e);
            after(context, taskJob, e);
        }
    }

    /**
     * 执行前
     *
     * @param context 工作执行上下文对象
     * @param sysJob 系统计划任务
     */
    protected void before(JobExecutionContext context, TaskJob sysJob)
    {
        threadLocal.set(new Date());
    }

    /**
     * 执行后
     *
     * @param context 工作执行上下文对象
     * @param sysJob 系统计划任务
     */
    protected void after(JobExecutionContext context, TaskJob sysJob, Exception e)
    {
        Date startTime = threadLocal.get();
        threadLocal.remove();

        long runMs = new Date().getTime() - startTime.getTime();
        log.info( "{}总共耗时{}毫秒",sysJob.getJobName(),runMs);
        if (e != null)
        {
            log.error(sysJob.getJobName()+"运行失败",e);
        }
        else
        {
            log.info( "{}运行成功",sysJob.getJobName());
        }

    }

    /**
     * 执行方法，由子类重载
     *
     * @param context 工作执行上下文对象
     * @param sysJob 系统计划任务
     * @throws Exception 执行过程中的异常
     */
    protected abstract void doExecute(JobExecutionContext context, TaskJob sysJob) throws Exception;
}
